﻿
using LiteVectorIndex.Engine;
using Newtonsoft.Json.Linq;
using System.Collections;
using System.IO;
using System.IO.Compression;
using System.Text.Json;
using System.Text.Json.Nodes;

namespace LiteVectorIndex
{
    /// <summary>
    /// 向量知识库
    /// </summary>
    public class GeneralConverter
    {

        /// <summary>
        /// 将对象转换为整数ID集合
        /// </summary>
        /// <param name="source">原始对象，支持多种类型</param>
        /// <returns>ID数组</returns>
        public static IEnumerable<int> ToIDs(object? source)
        {
            if (source == null)
            {
                return [];
            }

            if (source is IEnumerable<int>)
            {
                return (IEnumerable<int>)source;
            }

            if (source is string sourceString)
            {
                sourceString = sourceString.Trim('[', ']'); // 去除方括号   
                sourceString = sourceString.Replace(" ", ""); // 去除空格
                sourceString = sourceString.Replace("\r\n", ""); // 去除换行符

                var arrS = sourceString.Split(',');
                List<int> result = [];
                for (int i = 0; i < arrS.Length; i++)
                {
                    result.Add(ToInt(arrS[i]));
                }

                return result;
            }

            if (source is JArray jArray)
            {
                return [.. jArray.Select(x => ToInt(x))];
            }

            if (source is IEnumerable enumerable)
            {
                return [.. enumerable.Cast<object>().Select(x => ToInt(x))];
            }

            if (source is ArrayList arr)
            {
                return [.. arr.ToArray().Select(x => ToInt(x))];
            }

            if (source is IList list)
            {
                return [.. list.Cast<object>().Select(x => ToInt(x))];
            }

            if (source is JsonArray jsonArray)
            {
                return [.. jsonArray.Select(x => (x is JsonValue jsonValue) ? ToInt(jsonValue.AsObject()) : 0)];
            }

            return [];
        }

        /// <summary>
        /// 转换为ID和向量的元组集合
        /// </summary>
        /// <param name="json">特定格式的JSON字符串，形如[{\"id\":1,\"embedding\":[0.112,0.9871,...]},{\"id\":2,\"embedding\":[0.311,0.561,...]}]</param>
        /// <returns>元组集合</returns>
        /// <exception cref="Exception">JSON反序列化失败</exception>
        public static IList<(int Id, float[] Vector)> ToVectors(string json)
        {

            // 处理JSON字符串，形如：插入集合的向量数组，形如[{\"id\":1,\"embedding\":[0.112,0.9871,...]},{\"id\":2,\"embedding\":[0.311,0.561,...]}]
            if (string.IsNullOrEmpty(json))
                return [];

            try
            {
                var jsonArray = JsonSerializer.Deserialize<JsonArray>(json);
                if (jsonArray == null)
                    return [];
                return jsonArray.Select(item =>
                {
                    // 这个需要使用严格的匹配规则
                    if (item is JsonObject obj && obj.TryGetPropertyValue("id", out var idValue) && obj.TryGetPropertyValue("embedding", out var embeddingValue))
                    {
                        if (idValue == null || embeddingValue == null)
                            throw new Exception("每个对象必须包含'id'和'embedding'属性，且不能为空。");

                        int id = idValue.GetValue<int>();
                        float[] embedding = ToVector(embeddingValue.ToString());
                        return (id, embedding);
                    }
                    return default((int, float[]));
                }).Where(x => x.Item2 != null).ToList();
            }
            catch (Exception ex)
            {
                throw new Exception($"解析JSON失败: {ex.Message}");
            }

        }

        /// <summary>
        /// 转换为二维浮点数组
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static float[][] To2DVectors(object source)
        {

            if (source == null)
            {
                return [];
            }

            if (source is float[][] arrFloat2D)
            {
                return arrFloat2D; // 如果已经是二维浮点数组，直接返回
            }

            if (source is string sourceString)
            {

                sourceString = sourceString.Trim('[', ']'); // 去除方括号   
                sourceString = sourceString.Replace("\r\n", ""); // 去除换行符

                var arrS = sourceString.Split(["],["], StringSplitOptions.RemoveEmptyEntries);
                List<float[]> result = [];
                for (int i = 0; i < arrS.Length; i++)
                {
                    var vec = ToVector(arrS[i]);
                    if (vec != null)
                        result.Add(vec);
                }

                return [.. result];
            }

            if (source is IEnumerable enumerable)
            {
                return [.. enumerable.Cast<object>().Select(x => ToVector(x))];
            }

            if (source is ArrayList arr)
            {
                return [.. arr.ToArray().Select(x => ToVector(x))];
            }

            if (source is IList list)
            {
                return [.. list.Cast<object>().Select(x => ToVector(x))];
            }

            if (source is JsonArray jsonArray)
            {
                return [.. jsonArray.Select(x => ToVector(x))];
            }

            return [];
        }

        public static float[] ToVector(string? embeddingString)
        {
            if (string.IsNullOrEmpty(embeddingString))
            {
                return [];
            }
            embeddingString = embeddingString.Trim('[', ']'); // 去除方括号   
            embeddingString = embeddingString.Replace(" ", ""); // 去除空格
            embeddingString = embeddingString.Replace("\r\n", ""); // 去除换行符
            var arrS = embeddingString.Split(',');
            List<float> result = [];
            for (int i = 0; i < arrS.Length; i++)
            {
                result.Add(ToFloat(arrS[i]));
            }
            return [.. result];
        }

        /// <summary>
        /// 将对象转换为浮点数组
        /// </summary>
        /// <param name="target">原始对象，支持多种类型</param>
        /// <returns>浮点数组</returns>
        public static float[] ToVector(object? target)
        {
            if (target is float[] arrFloat)
            {
                return arrFloat; // 如果已经是浮点数组，直接返回
            }

            if (target is double[] arrDouble)
            {
                return [.. arrDouble.Select(x => (float)x)]; // 如果是双精度数组，转换为浮点数组
            }

            if (target is JArray jArray)
            {
                return [.. jArray.Select(x => ToFloat(x))]; // 处理JArray形式的向量
            }

            if (target is ArrayList arr)
            {
                return [.. arr.ToArray().Select(x => ToFloat(x))]; // 其他都需要转换为浮点数
            }

            if (target is string embeddingString)
            {
                return ToVector(embeddingString); // 处理字符串形式的向量
            }

            if (target is IList list)
            {
                return [.. list.Cast<object>().Select(x => ToFloat(x))]; // 其他都需要转换为浮点数
            }

            if (target is JsonArray jsonArray)
            {
                return [.. jsonArray.Select(x => (x is JsonValue jsonValue) ? (float)jsonValue : ToFloat(x))]; // 如果是JsonArray类型，转换为浮点数组
            }

            return ToVector(target?.ToString());

        }

        /// <summary>
        /// 将对象转换为浮点数
        /// </summary>
        /// <param name="source">原始对象，支持多种类型</param>
        /// <param name="defaultValue">默认值</param>
        /// <param name="nullValue">Null时的转换结果</param>
        /// <returns></returns>
        public static float ToFloat(object? source, float defaultValue = 0f, float nullValue = 0f)
        {
            if (source == null)
            {
                return nullValue;
            }
            if (source is float f)
            {
                return f;
            }
            if (source is double d)
            {
                return (float)d;
            }
            if (source is int i)
            {
                return (float)i;
            }
            if (source is long l)
            {
                return (float)l;
            }
            if (source is decimal m)
            {
                return (float)m;
            }

            if (source is JValue jv && jv.Type == JTokenType.Float)
            {
                return jv.ToObject<float>();
            }

            if (float.TryParse(source.ToString(), out var result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 将对象转换为整数
        /// </summary>
        /// <param name="source">原始对象，支持多种类型</param>
        /// <param name="defaultValue">默认值</param>
        /// <param name="nullValue">Null时的转换结果</param>
        /// <returns></returns>
        public static int ToInt(object? source, int defaultValue = -1, int nullValue = -1)
        {
            if (source == null) { return nullValue; }

            if (source is int f)
            {
                return f;
            }
            if (source is long d)
            {
                return (int)d;
            }

            if (source is JValue jv && jv.Type == JTokenType.Integer)
            {
                return jv.ToObject<int>();
            }

            if (int.TryParse(source.ToString(), out var result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }
    }
}
